package ru.samgtu.wst.plugin.sqlinj;


import java.util.HashSet;
import java.util.LinkedList;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.logging.Logger;

import ru.samgtu.wst.model.ConversationID;
import ru.samgtu.wst.model.ConversationModel;
import ru.samgtu.wst.model.FilteredConversationModel;
import ru.samgtu.wst.model.FrameworkModel;
import ru.samgtu.wst.model.HttpUrl;
import ru.samgtu.wst.model.Request;
import ru.samgtu.wst.plugin.AbstractPluginModel;

public class SqlInjectionModel extends AbstractPluginModel{
	private FrameworkModel _model;
	private LinkedList toBeAnalyzedQueue = new LinkedList();
	private Logger _logger = Logger.getLogger(getClass().getName());
	private Set testedURLandParameterpairs = new HashSet();
	private ConversationModel _conversationModel, _suspectedConversationModel;
	private String sqlTestString="'";
	
	public SqlInjectionModel(FrameworkModel model) {
		_model = model;
		
		_conversationModel = new FilteredConversationModel(model, model
				.getConversationModel()) {
			@Override
			public boolean shouldFilter(ConversationID id) {
				return !isVulnerable(id);
			}
		};

	}
	public ConversationModel getVulnerableConversationModel() {
		return _conversationModel;
	}

	public void setSqlVulnerable(ConversationID id, HttpUrl url) {
		_model.setUrlProperty(url, "injected", "TRUE");
		_model.setConversationProperty(id, "injected", "TRUE");
		
	}
	public String getSqlTestString(){
		return sqlTestString;
	}
	private boolean isTested(Request req, String vulnParam) {
		HttpUrl url = req.getURL();
		return testedURLandParameterpairs.contains(url.getSHPP() + vulnParam);
	}
	public boolean isVulnerable(ConversationID id) {
		return "TRUE".equals(_model.getConversationProperty(id, "injected"));
	}
	public boolean isVulnerable(HttpUrl url) {
		return "TRUE".equals(_model.getUrlProperty(url, "injected"));
	}
	
	public void enqueueRequest(Request req, String paramName) {
		synchronized (toBeAnalyzedQueue) {
			if (!isTested(req, paramName)) {
				toBeAnalyzedQueue.addLast(req);
				toBeAnalyzedQueue.notifyAll();
				testedURLandParameterpairs.add(req.getURL().getSHPP()
						+ paramName);
			}
		}
	}

	public Request dequeueRequest() {

		synchronized (toBeAnalyzedQueue) {
			try {
				while (toBeAnalyzedQueue.isEmpty()) {
					toBeAnalyzedQueue.wait();
					return null;
				}
				return (Request) toBeAnalyzedQueue.removeFirst();
			} catch (InterruptedException e) {
				return null;
			} catch (NoSuchElementException e) {
				return null;
			}
		}
	}
}
